package com.jxpanda.spring.module.auth.core;

import com.jxpanda.spring.module.auth.core.authentication.strategy.*;
import com.jxpanda.spring.module.auth.core.component.CaptchaReactiveService;
import com.jxpanda.spring.module.auth.core.exception.StrategyNotFoundException;
import com.jxpanda.spring.module.auth.core.register.strategy.DefaultUserDetailsRepositoryReactiveRegisterStrategy;
import com.jxpanda.spring.module.auth.core.register.strategy.OAuth2ReactiveRegisterStrategy;
import com.jxpanda.spring.module.auth.core.user.OAuth2ReactiveUserDetailsRepository;
import com.jxpanda.spring.module.auth.endpoint.GrantType;
import lombok.RequiredArgsConstructor;

import java.util.Map;

@RequiredArgsConstructor
public class OAuth2StrategyFactory {

    private final CaptchaReactiveService captchaReactiveService;

    private final OAuth2ReactiveUserDetailsRepository oAuth2ReactiveUserDetailsRepository;

    private final Map<String, OAuth2ReactiveUserDetailsRepository> oAuth2ReactiveUserDetailsRepositoryMap;

    public OAuth2ReactiveRegisterStrategy createRegisterStrategy(GrantType grantType, String repositoryBeanName) {
        return new DefaultUserDetailsRepositoryReactiveRegisterStrategy(selectRepository(repositoryBeanName));
    }

    public CollaborativeReactiveAuthenticationStrategy createAuthenticationStrategy(GrantType grantType, String repositoryBeanName) {
        OAuth2ReactiveUserDetailsRepository reactiveUserDetailsRepository = selectRepository(repositoryBeanName);
        return switch (grantType) {
            case PASSWORD ->
                    new UsernamePasswordCollaborativeReactiveAuthenticationStrategy(reactiveUserDetailsRepository);
            case PHONE_CAPTCHA, EMAIL_CAPTCHA -> {
                if (this.captchaReactiveService == null) {
                    throw new IllegalArgumentException("CaptchaReactiveService is null");
                }
                yield new CaptchaCollaborativeReactiveAuthenticationStrategy(this.captchaReactiveService, reactiveUserDetailsRepository);
            }
            case WECHAT_OPEN_PLATFORM ->
                    new WechatOpenPlatformCollaborativeReactiveAuthenticationStrategy(reactiveUserDetailsRepository);
            case WECHAT_MINI_PROGRAM ->
                    new WechatMiniProgramCollaborativeReactiveAuthenticationStrategy(reactiveUserDetailsRepository);
            default -> throw new IllegalArgumentException("Unsupported grant type: " + grantType);
        };
    }

    public OAuth2ReactiveUserDetailsRepository selectRepository(String repositoryBeanName) {
        return this.oAuth2ReactiveUserDetailsRepositoryMap.getOrDefault(repositoryBeanName, this.oAuth2ReactiveUserDetailsRepository);
    }

}
